home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 8: LINUX Games / Linux Cubed Series 8 - LINUX Games.iso / games / muds / pennmush.000 / pennmush-1.50-p8-linux.tar / pennmush / boolexp.c < prev    next >
C/C++ Source or Header  |  1993-04-05  |  9KB  |  411 lines

  1. /* boolexp.c */
  2.  
  3. #include "copyright.h"
  4.  
  5. #include <ctype.h>
  6. #include <string.h>
  7.  
  8. #include "db.h"
  9. #include "match.h"
  10. #include "externs.h"
  11. #include "config.h"
  12. #include "interface.h"
  13.  
  14. int check_attrib_lock();
  15.  
  16. int eval_boolexp(player, b, privs, nrecurs, locktype)
  17.     dbref player;
  18.     struct boolexp *b;
  19.     dbref privs;
  20.     int nrecurs;
  21.     int locktype;
  22. {
  23.   ATTR *a;
  24.   char tbuf1[BUFFER_LEN], tbuf2[BUFFER_LEN];
  25.  
  26.   if(player < 0 || player >= db_top)
  27.     return 0;
  28.  
  29.   if (nrecurs > MAX_DEPTH) {
  30.     notify(player,"Sorry, broken lock!");
  31.     return 0;
  32.   }
  33.  
  34.   if (b == TRUE_BOOLEXP) {
  35.     return 1;
  36.   } else {
  37.     switch (b->type) {
  38.       case BOOLEXP_IND:
  39.     if(b->sub1->type != BOOLEXP_CONST)
  40.       return 0;
  41.         nrecurs++;
  42.         switch (locktype) {
  43.     case BASICLOCK:
  44.       return (eval_boolexp(player, db[b->sub1->thing].key, privs, nrecurs,
  45.                    locktype));
  46.       break;
  47.     case USELOCK:
  48.       return (eval_boolexp(player, db[b->sub1->thing].usekey, privs,
  49.                    nrecurs, locktype));
  50.       break;
  51.     case ENTERLOCK:
  52.       return (eval_boolexp(player, db[b->sub1->thing].enterkey, privs,
  53.                    nrecurs, locktype));
  54.       break;
  55.     default:
  56.       /* should never be reached */
  57.       notify(player, "Broken lock!");
  58.       do_log(LT_ERR, 0, 0, "Bad lock type %d on object #%d",
  59.          locktype, b->thing);
  60.       return 0;
  61.     } break;
  62.       case BOOLEXP_AND:
  63.     return (eval_boolexp(player, b->sub1, privs, nrecurs, locktype)
  64.         && eval_boolexp(player, b->sub2, privs, nrecurs, locktype));
  65.       case BOOLEXP_OR:
  66.     return (eval_boolexp(player, b->sub1, privs, nrecurs, locktype)
  67.         || eval_boolexp(player, b->sub2, privs, nrecurs, locktype));
  68.       case BOOLEXP_NOT:
  69.     return !eval_boolexp(player, b->sub1, privs, nrecurs, locktype);
  70.       case BOOLEXP_CONST:
  71.     return (b->thing == player
  72.         || member(b->thing, db[player].contents));
  73.       case BOOLEXP_IS:
  74.     return (b->sub1->thing == player);
  75.       case BOOLEXP_CARRY:
  76.     return (member(b->sub1->thing,db[player].contents));
  77.       case BOOLEXP_OWNER:
  78.     return (Owner(b->sub1->thing) == Owner(player));
  79.       case BOOLEXP_ATR:
  80.     a = atr_complete_match(player, b->atr_lock->name, privs);
  81.     if(!a)
  82.       return 0;
  83.     strcpy(tbuf1, uncompress(b->atr_lock->text));
  84.     strcpy(tbuf2, uncompress(a->value));
  85.         return (int) local_wild_match(tbuf1, tbuf2);
  86.       case BOOLEXP_EVAL:
  87.     strcpy(tbuf1, uncompress(b->atr_lock->text));
  88.         return (int) check_attrib_lock(player, privs, b->atr_lock->name,
  89.                        tbuf1);
  90.       default:
  91.     do_log(LT_ERR, 0, 0, "Bad boolexp type %d in object #%d",
  92.            b->type, b->thing);
  93.     report();
  94.     return 0;
  95.       }                /* switch */
  96.     /* should never be reached */
  97.     do_log(LT_ERR, 0, 0, "Broken lock type %d in object called by #%d",
  98.        locktype, player);
  99.     return 0;
  100.   }                /* else */
  101. }
  102.  
  103. /* If the parser returns TRUE_BOOLEXP, you lose */
  104. /* TRUE_BOOLEXP cannot be typed in by the user; use @unlock instead */
  105. static const char *parsebuf;
  106. static dbref parse_player;
  107.  
  108. static void skip_whitespace()
  109. {
  110.   while (*parsebuf && isspace(*parsebuf))
  111.     parsebuf++;
  112. }
  113.  
  114. static struct boolexp *parse_boolexp_E();    /* defined below */
  115.  
  116. static struct boolexp *test_atr(s, c)
  117.      char *s;
  118.      char c;
  119. {
  120.   struct boolexp *b;
  121.   char tbuf1[BUFFER_LEN];
  122.  
  123.   strcpy(tbuf1, s);
  124.   for (s = tbuf1; *s && (*s != c); s++) ;
  125.   if (!*s)
  126.     return (0);
  127.   *s++ = 0;
  128.   if (strlen(tbuf1) == 0)
  129.     return (0);
  130.   b = alloc_bool();
  131.  
  132.   if (c == ':')
  133.     b->type = BOOLEXP_ATR;
  134.   else
  135.     b->type = BOOLEXP_EVAL;
  136.  
  137.   /* !!! Possible portability problem!!!!! */
  138.   b->atr_lock = alloc_atr(tbuf1, s);
  139.   return (b);
  140. }
  141.  
  142. /* L -> (E); L -> object identifier */
  143. static struct boolexp *parse_boolexp_L()
  144. {
  145.   struct boolexp *b;
  146.   char *p;
  147.   char tbuf1[BUFFER_LEN];
  148.  
  149.   skip_whitespace();
  150.   switch (*parsebuf) {
  151.     case '(':
  152.       parsebuf++;
  153.       b = parse_boolexp_E();
  154.       skip_whitespace();
  155.       if (b == TRUE_BOOLEXP || *parsebuf++ != ')') {
  156.     free_boolexp(b);
  157.     return TRUE_BOOLEXP;
  158.       } else {
  159.     return b;
  160.       }
  161.       /* break; */
  162.     default:
  163.       /* must have hit an object ref */
  164.       /* load the name into our buffer */
  165.       p = tbuf1;
  166.       while (*parsebuf
  167.          && *parsebuf != AND_TOKEN
  168.          && *parsebuf != OR_TOKEN
  169.          && *parsebuf != ')') {
  170.     *p++ = *parsebuf++;
  171.       }
  172.       /* strip trailing whitespace */
  173.       *p-- = '\0';
  174.       while (isspace(*p))
  175.     *p-- = '\0';
  176.  
  177.       /* check for an attribute */
  178.       b = test_atr(tbuf1, ':');
  179.       if (b)
  180.     return (b);
  181.  
  182.       /* check for an eval */
  183.       b = test_atr(tbuf1, '/');
  184.       if (b)
  185.     return b;
  186.  
  187.       b = alloc_bool();
  188.       b->type = BOOLEXP_CONST;
  189.  
  190.       /* do the match */
  191.       init_match(parse_player, tbuf1, TYPE_THING);
  192.       match_neighbor();
  193.       match_possession();
  194.       match_me();
  195.       match_absolute();
  196.       match_player();
  197.  
  198.       b->thing = match_result();
  199.  
  200.       if (b->thing == NOTHING) {
  201.     notify(parse_player,
  202.            tprintf("I don't see %s here.", tbuf1));
  203.     free_bool(b);
  204.     return TRUE_BOOLEXP;
  205.       } else if (b->thing == AMBIGUOUS) {
  206.     notify(parse_player,
  207.            tprintf("I don't know which %s you mean!", tbuf1));
  208.     free_bool(b);
  209.     return TRUE_BOOLEXP;
  210.       } else {
  211.     return b;
  212.       }
  213.       /* break */
  214.   }
  215. }
  216.  
  217. /* O -> $Identifier ; O -> L */
  218. static struct boolexp *parse_boolexp_O()
  219. {
  220.   struct boolexp *b2;
  221.   skip_whitespace();
  222.   if (*parsebuf == OWNER_TOKEN) {
  223.     parsebuf++;
  224.     b2 = alloc_bool();
  225.     b2->type = BOOLEXP_OWNER;
  226.     if (((b2->sub1 = parse_boolexp_L()) == TRUE_BOOLEXP) ||
  227.     (b2->sub1->type != BOOLEXP_CONST)) {
  228.       free_boolexp(b2);
  229.       return(TRUE_BOOLEXP);
  230.     } else
  231.       return (b2);
  232.   }
  233.   return (parse_boolexp_L());
  234. }
  235.  
  236. /* C -> +Identifier ; C -> O */
  237. static struct boolexp *parse_boolexp_C()
  238. {
  239.   struct boolexp *b2;
  240.   skip_whitespace();
  241.   if(*parsebuf == IN_TOKEN) {
  242.     parsebuf++;
  243.     b2 = alloc_bool();
  244.     b2->type = BOOLEXP_CARRY;
  245.     if(((b2->sub1 = parse_boolexp_L()) == TRUE_BOOLEXP) ||
  246.        (b2->sub1->type != BOOLEXP_CONST)) {
  247.       free_boolexp(b2);
  248.       return(TRUE_BOOLEXP);
  249.     } else
  250.       return(b2);
  251.   }
  252.   return (parse_boolexp_O());
  253. }
  254.  
  255. /* I -> =Identifier ; I -> C */
  256. static struct boolexp *parse_boolexp_I()
  257. {
  258.   struct boolexp *b2;
  259.   skip_whitespace();
  260.   if(*parsebuf == IS_TOKEN) {
  261.     parsebuf++;
  262.     b2 = alloc_bool();
  263.     b2->type = BOOLEXP_IS;
  264.     if(((b2->sub1 = parse_boolexp_L()) == TRUE_BOOLEXP) ||
  265.        (b2->sub1->type != BOOLEXP_CONST)){
  266.       free_boolexp(b2);
  267.       return(TRUE_BOOLEXP);
  268.     } else
  269.       return(b2);
  270.     }
  271.     return(parse_boolexp_C());
  272. }
  273.  
  274. /* A -> @L; A -> I */
  275. static struct boolexp *parse_boolexp_A()
  276. {
  277.   struct boolexp *b2;
  278.   skip_whitespace();
  279.   if(*parsebuf == AT_TOKEN) {
  280.     parsebuf++;
  281.     b2 = alloc_bool();
  282.     b2->type = BOOLEXP_IND;
  283.     if(((b2->sub1 = parse_boolexp_L()) == TRUE_BOOLEXP) ||
  284.        (b2->sub1->type != BOOLEXP_CONST)) {
  285.       free_boolexp(b2);
  286.       return(TRUE_BOOLEXP);
  287.     } else
  288.       return (b2);
  289.   }
  290.   return(parse_boolexp_I());
  291. }
  292.  
  293. /* F -> !F;F -> A */
  294. static struct boolexp *parse_boolexp_F()
  295. {
  296.   struct boolexp *b2;
  297.   skip_whitespace();
  298.   if (*parsebuf == NOT_TOKEN) {
  299.     parsebuf++;
  300.     b2 = alloc_bool();
  301.     b2->type = BOOLEXP_NOT;
  302.     if ((b2->sub1 = parse_boolexp_F()) == TRUE_BOOLEXP) {
  303.       free_boolexp(b2);
  304.       return (TRUE_BOOLEXP);
  305.     } else
  306.       return (b2);
  307.   }
  308.   return (parse_boolexp_A());
  309. }
  310.  
  311.  
  312. /* T -> F; T -> F & T */
  313. static struct boolexp *parse_boolexp_T()
  314. {
  315.   struct boolexp *b;
  316.   struct boolexp *b2;
  317.   if ((b = parse_boolexp_F()) == TRUE_BOOLEXP) {
  318.     return b;
  319.   } else {
  320.     skip_whitespace();
  321.     if (*parsebuf == AND_TOKEN) {
  322.       parsebuf++;
  323.  
  324.       b2 = alloc_bool();
  325.       b2->type = BOOLEXP_AND;
  326.       b2->sub1 = b;
  327.       if ((b2->sub2 = parse_boolexp_T()) == TRUE_BOOLEXP) {
  328.     free_boolexp(b2);
  329.     return TRUE_BOOLEXP;
  330.       } else {
  331.     return b2;
  332.       }
  333.     } else {
  334.       return b;
  335.     }
  336.   }
  337. }
  338.  
  339. /* E -> T; E -> T | E */
  340. static struct boolexp *parse_boolexp_E()
  341. {
  342.   struct boolexp *b;
  343.   struct boolexp *b2;
  344.   if ((b = parse_boolexp_T()) == TRUE_BOOLEXP) {
  345.     return b;
  346.   } else {
  347.     skip_whitespace();
  348.     if (*parsebuf == OR_TOKEN) {
  349.       parsebuf++;
  350.  
  351.       b2 = alloc_bool();
  352.       b2->type = BOOLEXP_OR;
  353.       b2->sub1 = b;
  354.       if ((b2->sub2 = parse_boolexp_E()) == TRUE_BOOLEXP) {
  355.     free_boolexp(b2);
  356.     return TRUE_BOOLEXP;
  357.       } else {
  358.     return b2;
  359.       }
  360.     } else {
  361.       return b;
  362.     }
  363.   }
  364. }
  365.  
  366. struct boolexp *parse_boolexp(player, buf)
  367.     dbref player;
  368.     const char *buf;
  369. {
  370.   parsebuf = buf;
  371.   parse_player = player;
  372.   return parse_boolexp_E();
  373. }
  374.  
  375. int check_attrib_lock(player, target, atrname, str)
  376.      dbref player;
  377.      dbref target;
  378.      const char *atrname;
  379.      const char *str;
  380. {
  381.   /* player is attempting to pass the lock on target, which has
  382.    * an attribute lock of the form  "atrname/value".
  383.    * This lock is passed if the equivalent of the MUSH function
  384.    * get_eval(target/atrname) is value. This does NOT do a wildcard
  385.    * match. It is also case-sensitive for matching.
  386.    */
  387.  
  388.   ATTR *a;
  389.   char *buff = NULL;
  390.   int match = 0;
  391.   char tbuf1[BUFFER_LEN];
  392.  
  393.   if (!atrname || !*atrname || !str || !*str)
  394.     return 0;
  395.  
  396.   /* fail if there's no matching attribute */
  397.   a = atr_get(target, strupper(atrname));
  398.   if (!a || (strlen(uncompress(a->value)) > BUFFER_LEN))
  399.     return 0;
  400.   strcpy(tbuf1, uncompress(a->value));
  401.  
  402.   /* perform pronoun substitution */
  403.   buff = exec(target, player, EV_STRIP | EV_FCHECK, tbuf1);
  404.   if (!strcmp(buff, str))
  405.     match = 1;
  406.  
  407.   if (buff)
  408.     free(buff);
  409.   return match;
  410. }
  411.